use std::io::{Error, Read, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::Arc;
use std::thread;


pub fn main() {
    println!("server to start");

    // 首先 bind and listen
    let listener = Arc::new(TcpListener::bind("0.0.0.0:12345").unwrap());

    //不引入num_cpus了，简单点
    let worker = 2;///num_cpus::get();
    let mut ths = Vec::new();


    //多个线程中共享listener,  似乎可以在多个线程中同时监听，提高单位时间内accept数量， 不知道是否存在“惊群” 
    for _ in 0..worker {
        // 利用 Arc 共享资源
        let listener = listener.clone();
	//起线程进行监听
        let th = thread::spawn(move || {
            loop {
    		println!("server start accept stream");
                // 在每个线程里去 accept
                let (stream, _addr) = listener.accept().unwrap();
		//得到stream 
    		println!("server  accepted stream");
		//这里照理说， 要启动线程处理每个stream,  更好的可以用select 来处理多个stream ， 或更更好的使用微线程来处理
                echo(stream);
            }
        });
        ths.push(th);
    }
    println!("server started");
    //等待所有线程结束
    join_all(ths);
    println!("server end");
}

fn join_all<T>(hs: Vec<thread::JoinHandle<T>>) {
    for h in hs {
        h.join().unwrap();
    }
}

fn echo(mut stream: TcpStream) {
    //定义一个可变u8数组
    let mut buf = [0u8; 1024];
    loop {
	//标准的错误处理  match
        let rsize = match stream.read(&mut buf) {
            Ok(size) => size, //正常结果
            Err(err) => panic!(err), //如果有错误，就引发系统异常退出
        };
        // EOF: read 0 size
        if rsize == 0 {
            break;
        }
   	println!("received:{}",  rsize);
        match stream.write_all(&buf[..rsize]) {
            Ok(_) => {}
            Err(err) => panic!(err),
        }
    }
}


